home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / DocShell / OpenDocX.cpp < prev    next >
Encoding:
Text File  |  1997-02-13  |  25.8 KB  |  889 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        OpenDocX.cpp
  3.  
  4.     Contains:    OpenDoc™ launcher application
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <17>    11.09.1996    NP        1386084: changed name of macro to
  13.                                     COMPATIBLEWITHSYSTEMPROCESS
  14.         <16>    22.07.1996    NP        1370914: Remove System Process.
  15.         <15>     7/11/96    TJ        Fixed Name of function to check for MacOS 8
  16.         <14>    11.07.1996    NP        1365143: Can't find system process error
  17.                                     messages.
  18.         <13>     6/23/96    NP        10002: Launch time speedups. 1323565:
  19.                                     Refuse to run under MacOS 8. 131565: change
  20.                                     name of system process to OpenDoc
  21.         <12>     6/19/96    NP        10002: Launch time speedups.
  22.         <11>     6/18/96    NP        10002: Launch time speedups. 1351368: Make
  23.                                     watch cursor go away.
  24.         <10>     6/14/96    NP        10002: Launch time speedups, 1303832: can't
  25.                                     make stationery when part editor lib is
  26.                                     already in use.
  27.          <9>    .06.1996    NP        10002: Launch time fixes, system process.
  28.          <8>    .05.1996    NP        1352438: Add call to NotifyLaunchFailed.
  29.          <7>      5/8/96    NP        1332028: Remove wasted function call for
  30.                                     launch time speedup.
  31.          <6>     4/15/96    TJ        Nolonger include ODXDef.h
  32.          <5>    .04.1996    NP        1337753: Never show splash screen.
  33.          <4>     3/14/96    NP        1258295: Displayed alert when app is
  34.                                     double-clicked.
  35.          <3>     1/15/96    TJ        Cleaned Up
  36.          <2>     1/15/96    JA        1269485: Display splash screen only 1st
  37.                                     time launched.
  38.         <26>    10/27/95    TÇ        Remove code which checks for 32 bit
  39.                                     addressing.
  40.         <25>    10/25/95    TÇ        1281409 GM: OpenDoc needs an AboutBox.
  41.         <24>    10/24/95    CC        1290114: Unload the scrap earlier to avoid
  42.                                     segment loader errors or crash on low
  43.                                     application heap space.
  44.         <23>     9/29/95    eeh        1287262: use ShellDef.h
  45.         <22>     8/26/95    TÇ        1269688 FB1:  There is an unnecessary
  46.                                     variable
  47.         <21>     6/23/95    CC        1260976: Added UnloadScrap() after toolbox
  48.                                     initialization.
  49.         <20>     5/19/95    TÇ        1249396 (was BB) OpenDoc shell should
  50.                                     serialize stationery creation., 1235942
  51.                                     Launching the OpenDoc pref file causes a
  52.                                     1000 exception to be thrown, 1234877 BB:
  53.                                     OpenDoc creates a bad document if
  54.                                     stationary launch fails.
  55.         <19>     4/15/95    TÇ        #1236388 The launcher splash screen no
  56.                                     longer goes away when a document window is
  57.                                     opened
  58.         <18>      4/7/95    eeh        1234548: check for 24-bit mode
  59.         <17>      4/7/95    eeh        1221297: generalize ODOC handler to
  60.                                     HandleRequiredEvent
  61.         <16>     3/31/95    TÇ        1223445 Launcher barfs generating
  62.                                     stationery from R/O library
  63.                                     1223493 BB: Creating a stationary under low
  64.                                     disk space.
  65.                                     1226040 Launcher crashes if CFM68K is not
  66.                                     installed.
  67.                                     1222903 Launcher doesn't check whether it
  68.                                     could open the resource file for a library.
  69.                                     1233754 OpenDoc™ Launcher splash screen
  70.                                     should use vers 2 resource.
  71.         <15>     2/20/95    TÇ        #1210979 BB: 5-$ Bugs need to be evaluated
  72.                                     and removed from Shell
  73.                                     #1221861 BB: Incomplete AOCE support needs
  74.                                     to be removed from OpenDoc
  75.         <14>      2/2/95    CG        Added qd global.
  76.         <13>      2/2/95    CG        #1205177:  "Editors" and "OpenDoc
  77.                                     Libraries" folders are being registered
  78.                                     with cfm (PPC only).
  79.         <12>      1/9/95    NP        1209979: No changes. Check in to force
  80.                                     rebuild for old runtime.
  81.         <11>      1/6/95    jpa        Fix error reporting in HandleOpenDocuments.
  82.                                     [1198075]
  83.         <10>    12/20/94    jpa        Wait longer for CFM error event [1198075]
  84.          <9>     12/5/94    jpa        Catch CFM errors on document launch.
  85.                                     Display splash screen. [1198075]
  86.          <8>    10/12/94    TÇ        68K: check to see if an AEDesc is null
  87.                                     before disposing
  88.          <7>     9/15/94    TÇ        #1183572 implement OpenDoc Shell PlugIns,
  89.                                     got rid of a few warnings
  90.          <6>      9/8/94    eeh        #1185443: fix HandleOpenDocuments to
  91.                                     preserve "special params".
  92.          <5>     8/25/94    TÇ        #1183223 Enabled launching of documents in
  93.                                     folders other than that of the OpenDoc
  94.                                     libraries
  95.          <4>     7/25/94    TÇ        added Jens' fixes for better error
  96.                                     reporting and a few bug fixes of my own
  97.          <3>     7/19/94    TÇ        fixed a bug in ODXstrncpy
  98.          <2>     7/14/94    TÇ        changed resource copying code to using
  99.                                     constant names instead of hard coded
  100.                                     constants (for PPC)
  101.          <1>     7/13/94    TÇ        first checked in
  102.          <0>     6/27/94    SV        SOMverted
  103.         <11>     4/19/94    TÇ        Don't append a null character onto the end
  104.                                     of the name of the stationery file because
  105.                                     AFP chokes on it.
  106.         <10>     4/18/94    TÇ        Another fix for Symantec.  This time to
  107.                                     ODXstrncpy.
  108.          <9>     4/18/94    HL        Fixed Symantec Compilation.
  109.          <8>     4/18/94    TÇ        #1144379 Stationery model & generation have
  110.                                     been fixed to enable dragging & dropping of
  111.                                     stationery onto open documents.
  112.          <7>     4/11/94    TÇ        #1155854 Use CustomPutFile for Save A Copy.
  113.                                     Checks to make sure document's resource
  114.                                     fork was properly opened.
  115.          <6>     3/24/94    eeh        bug #1153053: Changes for PPC nativity (or
  116.                                     is it nativeness...?)
  117.          <5>     3/17/94    CG        #1151392: Removed #include ConstDef.h.
  118.          <4>     3/16/94    eeh        bug #1149649 cont'd: CopyNonDPParams needed
  119.                                     a return statement for Symantec
  120.          <3>     3/16/94    eeh        bug #1149649: added CopyNonDPParams
  121.          <2>     3/10/94    eeh        bug #1149632: added alias param to
  122.                                     LaunchDocument()
  123.         <14>      2/9/94    TÇ        PowerPC header fixes
  124.         <13>     1/18/94    TÇ        conserve type and creator of documents
  125.                                     being opened
  126.         <12>    12/17/93    TÇ        removed bogus semicolon at the end of the
  127.                                     line "    if (needUpdate);"
  128.         <11>    12/17/93    eeh        Code to install 'scsz' resource in
  129.                                     documents.
  130.         <10>     12/1/93    TÇ        added calls to FlushInstructionCache()
  131.                                     FlushDataCache() right before
  132.                                     LaunchApplication to fix 040 data cache vs.
  133.                                     instruction cache problem with copying
  134.                                     resources as data then launching a document
  135.                                     which uses them as code.
  136.          <9>    11/30/93    TÇ        added a cast to Ptr to pacify CFront
  137.          <8>    11/23/93    TÇ        mostly formatting
  138.          <7>    10/28/93    TÇ        use sizeof(FSSpec) instead of
  139.                                     GetPtrSize(theDocument)
  140.          <6>    10/27/93    TÇ        more of the same.
  141.          <5>    10/26/93    TÇ        nil out fields of AEDesc.
  142.          <4>    10/26/93    TÇ        add code to construct 'ODOC' aevt and pass
  143.                                     it along in the LaunchApplication call to
  144.                                     the document being launched
  145.          <3>    10/26/93    TÇ        need to also use CODE 2 "32-bit blah blah
  146.                                     blah" resource
  147.          <2>    10/23/93    TÇ        added code to verify and update CODE 0,
  148.                                     CODE 1, and SIZE -1 resource in documents
  149.                                     before they are launched
  150.          <1>    10/18/93    TÇ        first checked in
  151.  
  152.     To Do:
  153.     In Progress:
  154.         
  155. */
  156.  
  157.  
  158.  
  159. /*
  160.  
  161. This is the OpenDoc™ extension which is actually an application.
  162. The sole purpose of this extension is to satisfy the currnt "APPL" launching model in the Finder.
  163. When OpenDoc™ documents are double-clicked in the Finder, 
  164. Finder notices that the creator of the documents is the same as this extension,
  165. then launches this extension with those documents.
  166. The OpenDoc™ extension verifies and fixes if necessary,
  167. the resources in the documents,
  168. then launches the documents using the ProcessManager directly and quits.
  169.  
  170. */
  171.  
  172. #define ppcinterfaces        /* keeps GX headers quiet */
  173.  
  174. #ifndef __TYPES__
  175. #include <Types.h>
  176. #endif
  177.  
  178. #ifndef __GESTALTEQU__
  179. #include <GestaltEqu.h>
  180. #endif
  181.  
  182. #ifndef __TEXTUTILS__
  183. #include <TextUtils.h>
  184. #endif
  185.  
  186. #ifndef __OSEVENTS__
  187. #include <OSEvents.h>
  188. #endif
  189.  
  190. #ifndef __QUICKDRAW__
  191. #include <Quickdraw.h>
  192. #endif
  193.  
  194. #ifndef __FONTS__
  195. #include <Fonts.h>
  196. #endif
  197.  
  198. #ifndef __FILES__
  199. #include <Files.h>
  200. #endif
  201.  
  202. #ifndef __RESOURCES__
  203. #include <Resources.h>
  204. #endif
  205.  
  206. #ifndef __EVENTS__
  207. #include <Events.h>
  208. #endif
  209.  
  210. #ifndef __APPLEEVENTS__
  211. #include <AppleEvents.h>
  212. #endif
  213.  
  214. #ifndef __DIALOGS__
  215. #include <Dialogs.h>
  216. #endif
  217.  
  218. #ifndef __MENUS__
  219. #include <Menus.h>
  220. #endif
  221.  
  222. #ifndef __OSUTILS__
  223. #include <OSUtils.h>
  224. #endif
  225.  
  226. #ifndef __TOOLUTILS__
  227. #include <ToolUtils.h>
  228. #endif
  229.  
  230. #ifndef __ERRORS__
  231. #include <Errors.h>
  232. #endif
  233.  
  234. #ifndef __SCRAP__
  235. #include <Scrap.h>
  236. #endif
  237.  
  238.  
  239. #ifndef _REGISTER_
  240. #include <RegisterFileLibs.h>
  241. #endif
  242.  
  243. #ifndef _SHELLDEF_
  244. #include "ShellDef.h"
  245. #endif
  246.  
  247. #ifndef _ODPRCS_
  248. #include "ODPrcs.h"
  249. #endif
  250.  
  251. #ifndef _ODXDPFNS_
  252. #include "ODXDpFns.h"
  253. #endif
  254.  
  255. #ifndef _ODXFUNCS_
  256. #include "ODXFuncs.h"
  257. #endif
  258.  
  259. #ifndef _PASCLSTR_
  260. #include "PasclStr.h"
  261. #endif
  262.  
  263. #ifndef _ERRUTILS_
  264. #include "ErrUtils.h"
  265. #endif
  266.  
  267. #ifndef ODDebug
  268. #error "Expected \"ODDEBUG\" to be defined."
  269. #endif
  270.  
  271. //==============================================================================
  272. // Constants
  273. //==============================================================================
  274.  
  275. const short kLaunchFailedAlert = 130;
  276. const short kGenericLaunchFailedAlert = 129;
  277.  
  278.  
  279. const long kQuitDelay          =  5 * 60;        /* Wait 1 second for an Apple event */
  280. const long kWaitForErrorDelay =  8 * 60;        /* Wait 8 seconds after trying to launch */
  281.  
  282.  
  283. #define SPLASHSCREEN 0                /* 1 enables splash screen, 0 disables */
  284.  
  285. //==============================================================================
  286. // Globals
  287. //==============================================================================
  288.  
  289. #ifndef __MWERKS__
  290. QDGlobals qd;
  291. #endif
  292.  
  293. FSSpec    gFileSpec;
  294.  
  295. //==============================================================================
  296. // Macros
  297. //==============================================================================
  298.  
  299. #define CHECK(EXPR)    if((err=(EXPR)) == noErr) ; else return err
  300. #if ODDebug
  301. #define LauncherDebugStr(x) DebugStr(CToPascalString(x))
  302. #else
  303. #define LauncherDebugStr(x)
  304. #endif
  305.  
  306. //==============================================================================
  307. // Function Prototypes
  308. //==============================================================================
  309.  
  310. static DialogPtr    gSplashScreen = NULL;
  311. static long            gQuitTime;
  312.  
  313. void            main( );
  314. static void        MainEventLoop( );
  315. static Boolean    FirstTimeLaunched( );
  316. static Boolean    ColorScreen( );
  317.  
  318. //static OSErr    CheckAppleEventForMissingParams(AppleEvent *theAppleEvent);
  319.  
  320. static pascal OSErr    HandleOpenAppEvent(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon);
  321. static pascal OSErr    NoOpAEHandler(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon);
  322. static OSErr        GetOurCreator(OSType& type);
  323. static OSErr            ChangeOurCreator(OSType);
  324. static void            BumpOurFolderModDate();
  325. static OSErr        ReenableSystemProcess(FSSpec* fileSpec);
  326. static OSErr        GetCreator(FSSpec* fileSpec, OSType& type);
  327. static OSErr        ChangeCreator(FSSpec* fileSpec, OSType type);
  328. static OSErr        EnableApp(FSSpec* fileSpec);
  329. static OSErr        EnableAppIfNotAlready(FSSpec* fileSpec);
  330. static OSErr        DisableOurselves(FSSpec* fileSpec, OSType newSignature);
  331. static OSErr        SimpleLaunchApp(FSSpec* fileSpec);
  332. static void            DoTheRenamingThang(StringPtr newNameForSystemProcess);
  333.  
  334. //==============================================================================
  335. // OpenDocX Main and Event Loop
  336. //==============================================================================
  337.  
  338. //------------------------------------------------------------------------------
  339. // main
  340. //------------------------------------------------------------------------------
  341.  
  342. void main(void)
  343. {
  344.     MaxApplZone();
  345.     MoreMasters();
  346.  
  347.     // The scrap is copied into our application heap when the process is launched,
  348.     // occuping space otherwise used for launching documents.
  349.     // If the scrap is just the right size (approx. 30K), there isn't enough
  350.     // heap space left to launch a single document (the launcher will bail with 
  351.     // error -108).  Worse, if the scrap is just the right size, around 40K, 
  352.     // InitWindows will hang the system.  To avoid this, always unload the scrap.
  353.     // Testing for a nil scrap handle seems to avoid a write to nil by UnloadScrap.
  354.     // [cc]
  355.     if ( InfoScrap()->scrapHandle != nil )
  356.         UnloadScrap();
  357.  
  358.     InitGraf((Ptr)&qd.thePort);
  359.     InitFonts();
  360.     InitWindows();
  361.     InitMenus();
  362.     TEInit();
  363.     InitDialogs(nil);
  364.  
  365.     long gestaltResponse;
  366.     if ((Gestalt(gestaltCFMAttr, &gestaltResponse) != noErr) ||
  367.         !(gestaltResponse & (1<<gestaltCFMPresent)))
  368.     {
  369.         ReportDocumentError("\p",fragMgrInitErr);
  370.         return;
  371.     }
  372.  
  373.     if (RunningUnderMacOS8())
  374.         return;
  375. #define COMPATIBLEWITHSYSTEMPROCESS 0
  376. #if COMPATIBLEWITHSYSTEMPROCESS
  377.     // DISABLE OURSELVES IF WE ARE RUNNING IN A SYSTEM LATER THAN 7.5
  378.     ProcessSerialNumber psn = {0, kCurrentProcess};
  379.     ProcessInfoRec        info;
  380.  
  381.     info.processInfoLength = sizeof(ProcessInfoRec);
  382.     info.processName = NULL;
  383.     info.processAppSpec = &gFileSpec;
  384.  
  385.     if (GetProcessInformation(&psn, &info))
  386.         LauncherDebugStr("main: Totally unexpected error from GetProcessInformation.");
  387.     else
  388.     {
  389.         OSType    creator;
  390.         OSErr    error;
  391.         FSSpec    fileSpec;
  392.  
  393.         error = GetOurCreator(creator);
  394.         if (error)
  395.             LauncherDebugStr("main: Totally unexpected error from GetOurCreator.");
  396.         else
  397.         {
  398.             if (!IsSystem753OrGreater())
  399.             {
  400.                 if (creator != kODShellSignature)
  401.                     EnableApp(&gFileSpec);
  402.             }
  403.             else
  404.             {
  405.                 // THIS IS THE CASE I CARE MORE ABOUT. USER CAN ONLY UPGRADE A
  406.                 //    PARTICULAR SYSTEM, NOT DOWNGRADE IT.
  407.                 if (creator != kODDisabledProcessSignature)
  408.                 {
  409.                     Str255    newSystemProcessName;
  410.  
  411.                     if (!ReenableSystemProcess(&fileSpec))
  412.                     {
  413.                         if(!DisableOurselves(&gFileSpec,
  414.                                             kODDisabledProcessSignature))
  415.                             DoTheRenamingThang(newSystemProcessName);
  416.                     }
  417.                     CopyPascalString(fileSpec.name, newSystemProcessName);
  418.  
  419.                     SimpleLaunchApp(&fileSpec);
  420.                 }
  421.             }
  422.         }
  423.     }
  424. #endif /* COMPATIBLEWITHSYSTEMPROCESS */
  425.     SetCursor(*GetCursor(watchCursor));
  426.  
  427.     AEEventHandlerUPP odocUPP = NewAEEventHandlerProc(HandleRequiredEvent);
  428.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  429.             odocUPP, 0, false);
  430.     (void) AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  431.             odocUPP, 0, false);
  432.  
  433.     AEEventHandlerUPP openAppUPP = NewAEEventHandlerProc(HandleOpenAppEvent);
  434.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  435.             openAppUPP, 0, false); // no refcon, not system handler
  436.  
  437. //    (void) AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  438. //            noOpUPP, 0, false);
  439.  
  440.     // Install a handler for both "launch-failed" notification events
  441.     // so we can notify the user:
  442.     AEEventHandlerUPP handleErrUPP = NewAEEventHandlerProc(HandleLaunchFailed);
  443.     (void) AEInstallEventHandler(kCoreEventClass, kAEApplicationDied,
  444.             handleErrUPP, 0, false);
  445.     (void) AEInstallEventHandler(kCFMLaunchFailedEventClass, kCFMLaunchFailedEventID,
  446.             handleErrUPP, 0, false);
  447.     
  448.     MainEventLoop();
  449. }
  450.  
  451. //------------------------------------------------------------------------------
  452. //  MainEventLoop
  453. //------------------------------------------------------------------------------
  454.  
  455. static void MainEventLoop(void)
  456. {
  457.     EventRecord        anEvent;
  458.     
  459.     FlushEvents(everyEvent,0);
  460.     
  461. #if SPLASHSCREEN
  462.     if( !AreODDocumentsRunning() && FirstTimeLaunched() )
  463.         gSplashScreen = ShowAboutScreen();
  464. #endif
  465.  
  466.     for( gQuitTime=TickCount()+kQuitDelay; TickCount()<gQuitTime; ) {
  467.         (void) WaitNextEvent(everyEvent,&anEvent,5,(RgnHandle) nil);
  468.         switch (anEvent.what)
  469.         {
  470.             case nullEvent:
  471.                 break;
  472.             
  473.             case osEvt:
  474.                 break;
  475.  
  476.             case kHighLevelEvent:
  477.                 AEProcessAppleEvent(&anEvent);
  478.                 break;
  479.             
  480.             default:
  481.                 if( IsDialogEvent(&anEvent) ) {
  482.                     DialogPtr whichDlog;
  483.                     short itemHit;
  484.                     if( DialogSelect(&anEvent,&whichDlog,&itemHit) && itemHit>0 )
  485.                         return;
  486.                 } else
  487.                     return;
  488.         }
  489.     }
  490. }
  491.  
  492. //------------------------------------------------------------------------------
  493. // FirstTimeLaunched
  494. //------------------------------------------------------------------------------
  495.  
  496. static Boolean FirstTimeLaunched( )
  497. {
  498.     /* To figure out if this is the first time launched today, check the mod
  499.        date of the "OpenDoc Preferences" file and compare it with today's date.
  500.        If it's earlier, this is the first time today; set the mod date to the
  501.        current date/time to signal that the launcher has run today. */
  502.     
  503.     FSSpec prefss;
  504.     if( GetPrefsFileSpec(&prefss) != noErr )
  505.         return true;
  506.     
  507.     CInfoPBRec pb;
  508.     pb.hFileInfo.ioNamePtr = prefss.name;
  509.     pb.hFileInfo.ioFDirIndex = 0;
  510.     pb.hFileInfo.ioVRefNum = prefss.vRefNum;
  511.     pb.hFileInfo.ioDirID = prefss.parID;
  512.     OSErr error = PBGetCatInfoSync(&pb);
  513.     if( error )
  514.         return (error==fnfErr);
  515.     
  516.     // Convert mod-time to date format, and get current date:
  517.     DateTimeRec prefsDate,curDate;
  518.     SecondsToDate(pb.hFileInfo.ioFlMdDat,&prefsDate);
  519.     GetTime(&curDate);
  520.  
  521.     // Compare:
  522.     if( prefsDate.year==curDate.year && prefsDate.month==curDate.month && prefsDate.day==curDate.day )
  523.         return false;
  524.     
  525.     // Not yet launched today. Bump mod date of file & return true:
  526.     GetDateTime(&pb.hFileInfo.ioFlMdDat);
  527.     pb.hFileInfo.ioDirID = prefss.parID;
  528.     PBSetCatInfoSync(&pb);
  529.     return true;
  530. }
  531.  
  532. //==============================================================================
  533. // Error reporting
  534. //==============================================================================
  535.  
  536. void ReportDocumentError(StringPtr docName, OSErr err)
  537. {    
  538.     // If it's not legal to interact with the user, do nothing:
  539.     if(AEInteractWithUser(0,NULL,NULL) == errAENoUserInteraction)
  540.         return;
  541.     
  542.     // Bring myself to the front:
  543.     ProcessSerialNumber psn;
  544.     psn.highLongOfPSN = 0;
  545.     psn.lowLongOfPSN = kCurrentProcess;
  546.     SetFrontProcess(&psn);
  547.     
  548. #if SPLASHSCREEN
  549.     if( gSplashScreen ) {
  550.         DisposeDialog(gSplashScreen);
  551.         gSplashScreen = NULL;
  552.     }
  553. #endif
  554.  
  555.     // Display the alert:
  556.     short alertID = docName[0] ?kODXErrAlert :kODXAnonErrAlert;
  557.     if( Get1Resource('ALRT',alertID) ) {
  558.         unsigned char errStr[12];
  559.         NumToString(err,errStr);
  560.         ParamText(docName,errStr,NULL,NULL);
  561.         InitCursor();
  562.         StopAlert(alertID, NULL);
  563.     } else {
  564.         SysBeep(3);
  565.         SysBeep(3);
  566.     }
  567. }
  568.  
  569. //==============================================================================
  570. // Apple Event handlers
  571. //==============================================================================
  572.  
  573. //------------------------------------------------------------------------------
  574. // HandleOpenAppEvent
  575. //
  576. //    We only expect to handle open-document events. If we get an open-application
  577. //    event, then the user must have double-clicked us. This doesn't do anything,
  578. //    so we put up an alert telling him so.
  579. //------------------------------------------------------------------------------
  580.  
  581. static pascal OSErr HandleOpenAppEvent(
  582.     AppleEvent * /*theAppleEvent*/,
  583.     AppleEvent * /*reply*/,
  584.     long /*refCon*/)
  585. {
  586.     SetCursor(&qd.arrow);
  587.     CautionAlert(kODXDoubleClickAlert, NULL);
  588.     return noErr;
  589. }
  590.  
  591. //------------------------------------------------------------------------------
  592. // NoOpAEHandler
  593. //
  594. //    NP: No reason to have this as far as I know
  595. //------------------------------------------------------------------------------
  596.  
  597. static pascal OSErr NoOpAEHandler(
  598.     AppleEvent * /*theAppleEvent*/,
  599.     AppleEvent * /*reply*/,
  600.     long /*refCon*/)
  601. {
  602.     return(noErr);
  603. }
  604.  
  605. //------------------------------------------------------------------------------
  606. //  NotifyLaunchFailed
  607. //------------------------------------------------------------------------------
  608.  
  609. void NotifyLaunchFailed(OSErr launchError, Str255 appName, Str255 libName)
  610. {
  611.     unsigned char    launchErrorString[12];
  612.     
  613.     // Force myself to the foreground:
  614.     ProcessSerialNumber psn = {0, kCurrentProcess};
  615.     (void) SetFrontProcess(&psn);
  616.     
  617. #if SPLASHSCREEN
  618.     if( gSplashScreen ) {
  619.         DisposeDialog(gSplashScreen);
  620.         gSplashScreen = NULL;
  621.     }
  622. #endif
  623.  
  624.     InitCursor();
  625.  
  626.     NumToString(launchError, launchErrorString);
  627.  
  628.     if( appName[0]==0 )
  629.     {
  630.         LauncherDebugStr("No document name available for dialog.");
  631.         ParamText(NULL, launchErrorString, NULL, NULL);
  632.         StopAlert(kGenericLaunchFailedAlert, NULL);
  633.     }
  634.     else
  635.     {
  636.         short index;
  637.         Str255 errorDescription;
  638.         if( launchError <= -2800 && launchError >= -2824 )
  639.             index = 2-2800-launchError;        // Maps -2800..-2824 -> 2..26
  640.         else
  641.             index = 1;
  642.         GetIndString(errorDescription, kLaunchFailedErrStrings, index);
  643.         ParamText(appName, errorDescription, libName, launchErrorString);
  644.         StopAlert(kLaunchFailedAlert, NULL);
  645.     }
  646. }
  647.  
  648. //------------------------------------------------------------------------------
  649. //  DocumentLaunched
  650. //
  651. //
  652. //------------------------------------------------------------------------------
  653.  
  654. void DocumentLaunched()
  655. {
  656.     // Give time for error to come back
  657.     gQuitTime = TickCount() + kWaitForErrorDelay;
  658. }
  659.  
  660. //------------------------------------------------------------------------------
  661. //  ReportErrorGeneric
  662. //------------------------------------------------------------------------------
  663.  
  664. void ReportErrorGeneric(StringPtr errorString)
  665. {
  666.     ReportErrorSimple(errorString);
  667. }
  668.  
  669. //------------------------------------------------------------------------------
  670. //    GetOurCreator
  671. //------------------------------------------------------------------------------
  672.  
  673. static OSErr GetOurCreator(OSType& type)
  674. {
  675.     return GetCreator(&gFileSpec, type);
  676. }
  677.  
  678. //------------------------------------------------------------------------------
  679. //    ChangeOurCreator
  680. //------------------------------------------------------------------------------
  681.  
  682. static OSErr ChangeOurCreator(OSType type)
  683. {
  684.     return ChangeCreator(&gFileSpec, type);
  685. }
  686.  
  687. //------------------------------------------------------------------------------
  688. //    GetCreator
  689. //------------------------------------------------------------------------------
  690.  
  691. static OSErr GetCreator(FSSpec* fileSpec, OSType& type)
  692. {
  693.     FInfo    fileInfo;
  694.     OSErr    error;
  695.     
  696.     error = FSpGetFInfo(fileSpec, &fileInfo);
  697.     type = fileInfo.fdCreator;
  698.     
  699.     return error;
  700. }
  701.  
  702. //------------------------------------------------------------------------------
  703. //    ChangeCreator
  704. //------------------------------------------------------------------------------
  705.  
  706. static OSErr ChangeCreator(FSSpec* fileSpec, OSType type)
  707. {
  708.     OSErr    error;
  709.     FInfo    fileInfo;
  710.         
  711.     error = FSpGetFInfo(fileSpec, &fileInfo);
  712.     if (!error)
  713.     {
  714.         fileInfo.fdCreator = type;
  715.         error = FSpSetFInfo(fileSpec, &fileInfo);
  716.         if (!error)
  717.             BumpOurFolderModDate();
  718.     }
  719.     
  720.     return error;
  721. }
  722.  
  723. //------------------------------------------------------------------------------
  724. //    EnableApp
  725. //------------------------------------------------------------------------------
  726.  
  727. OSErr EnableApp(FSSpec* fileSpec)
  728. {
  729.     OSErr    error;
  730.  
  731.     error = ChangeCreator(fileSpec, kODShellSignature);
  732.     if (!error)
  733.         ChangeDesktopDatabase(fileSpec, kODAddAPPL);
  734.     
  735.     return error;
  736. }
  737.  
  738. //------------------------------------------------------------------------------
  739. //    EnableAppIfNotAlready
  740. //
  741. //    Don't want to hit the desktop database if we don't have to.
  742. //------------------------------------------------------------------------------
  743.  
  744. OSErr EnableAppIfNotAlready(FSSpec* fileSpec)
  745. {
  746.     OSErr    error;
  747.     OSType    type;
  748.  
  749.     error = GetCreator(fileSpec, type);
  750.  
  751.     if (!error && type != kODShellSignature)
  752.         EnableApp(fileSpec);
  753.     
  754.     return error;
  755. }
  756.  
  757. //------------------------------------------------------------------------------
  758. //    SimpleLaunchApp
  759. //------------------------------------------------------------------------------
  760.  
  761. OSErr SimpleLaunchApp(FSSpec* fileSpec)
  762. {
  763.     LaunchParamBlockRec    launchPB;
  764.  
  765.     launchPB.launchBlockID = extendedBlock;
  766.     launchPB.launchEPBLength = extendedBlockLen;
  767.     // HOW ABOUT OTHER FLAGS?
  768.     launchPB.launchControlFlags = launchContinue
  769.                                     | launchNoFileFlags
  770.                                     | launchDontSwitch;
  771.     launchPB.launchAppSpec = fileSpec;
  772.     launchPB.launchAppParameters = NULL;
  773.     
  774.     return LaunchApplication(&launchPB);
  775. }
  776.  
  777. //------------------------------------------------------------------------------
  778. //    DisableOurselves
  779. //------------------------------------------------------------------------------
  780.  
  781. OSErr DisableOurselves(FSSpec* fileSpec, OSType newSignature)
  782. {
  783.     OSErr    error;
  784.  
  785.     error = ChangeCreator(fileSpec, newSignature);
  786.     if (!error)
  787.         ChangeDesktopDatabase(fileSpec, kODRemoveAPPL);
  788.  
  789.     return error;
  790. }
  791.  
  792. //------------------------------------------------------------------------------
  793. //    BumpFolderModDate
  794. //
  795. //    Stolen from PlfmFile.cpp. Original code can be used when the launcher is
  796. //    revved to use OpenDoc (like the system process).
  797. //------------------------------------------------------------------------------
  798.  
  799. static void BumpOurFolderModDate()
  800. {
  801.     CInfoPBRec    theParamBlock;
  802.  
  803.     memset (&theParamBlock, 0, sizeof(theParamBlock));
  804.     // ioNamePtr = 0
  805.     theParamBlock.dirInfo.ioFDirIndex = -1;
  806.     theParamBlock.dirInfo.ioVRefNum = gFileSpec.vRefNum;
  807.     theParamBlock.dirInfo.ioDrDirID = gFileSpec.parID;
  808.     OSErr err = PBGetCatInfoSync(&theParamBlock);
  809.     if( err )
  810.         LauncherDebugStr("BumpFolderModDate: Couldn't get dir mod date.");
  811.     else
  812.     {
  813.         ODULong newTime;
  814.  
  815.         GetDateTime(&newTime);
  816.         // set to the future if it is now
  817.         if (theParamBlock.dirInfo.ioDrMdDat >= newTime)
  818.             ++newTime;
  819.         theParamBlock.dirInfo.ioDrMdDat = newTime;
  820.         err = PBSetCatInfoSync(&theParamBlock);
  821.         if( err )
  822.             LauncherDebugStr("BumpFolderModDate: Couldn't bump dir mod date.");
  823.     }
  824. }
  825.                 
  826. //------------------------------------------------------------------------------
  827. //    ReenableSystemProcess
  828. //------------------------------------------------------------------------------
  829.  
  830. OSErr ReenableSystemProcess(FSSpec* fileSpec)
  831. {
  832.     OSErr        error;
  833.     StringPtr    string;
  834.  
  835.     string = *GetString(kSHLSystemProcessNameResID);
  836.     CopyPascalString(fileSpec->name, string);
  837.  
  838.     // TRY TO FIND THE SYSTEM PROCESS WHERE THE INSTALLER PUTS IT
  839.     error = GetOpenDocLibsFolderInfo(&(fileSpec->parID), &(fileSpec->vRefNum));
  840.     if (!error)
  841.         error = EnableAppIfNotAlready(fileSpec);
  842.  
  843.     if (error)
  844.     {
  845.         // MAYBE IT HAS BEEN RENAMED
  846.         error = FindODLibFileWithSignature(fileSpec->name,
  847.                                             fileSpec->vRefNum,
  848.                                             fileSpec->parID,
  849.                                             kODSystemProcessSignature);
  850.         if (!error)
  851.             error = EnableAppIfNotAlready(fileSpec);
  852.     }
  853.  
  854.     return error;
  855. }
  856.  
  857. //------------------------------------------------------------------------------
  858. //    DoTheRenamingThang
  859. //
  860. //    Ourselves        ->    some disabled name
  861. //    System Process    ->    "OpenDoc™"
  862. //------------------------------------------------------------------------------
  863.  
  864. void DoTheRenamingThang(StringPtr newNameForSystemProcess)
  865. {
  866.     FSSpec            fileSpec;
  867.     OSErr            error;
  868.     Str255            oldLauncherName;
  869.  
  870.     // TRY TO FIND SYSTEM PROCESS WHERE THE INSTALLER PUTS IT
  871.     CopyPascalString(fileSpec.name, *GetString(kSHLSystemProcessNameResID));
  872.     error = GetOpenDocLibsFolderInfo(&fileSpec.parID, &fileSpec.vRefNum);
  873.     if (!error)
  874.     {
  875.         CopyPascalString(oldLauncherName, *GetString(kSHLOldLauncherNameResID));
  876.         error = FSpRename(&gFileSpec, oldLauncherName);
  877.         if (!error)
  878.         {
  879.             CopyPascalString(newNameForSystemProcess,
  880.                                 *GetString(kSHLLauncherNameResID));
  881.             ChangeDesktopDatabase(&fileSpec, kODRemoveAPPL);
  882.             error = FSpRename(&fileSpec, newNameForSystemProcess);
  883.             CopyPascalString(fileSpec.name, newNameForSystemProcess);
  884.             ChangeDesktopDatabase(&fileSpec, kODAddAPPL);
  885.         }
  886.     }
  887. }
  888.  
  889.